package com.hyd.issues;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.interceptor.ParameterAware;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * (description)
 *
 * @author yiding.he
 */
public class BaseAction
        implements SessionAware, RequestAware, ParameterAware, ServletRequestAware, ServletResponseAware {

    protected Map<String, Object> session = new HashMap<String, Object>();

    protected Map<String, Object> request = new HashMap<String, Object>();

    protected Map<String, String[]> parameters = new HashMap<String, String[]>();

    protected HttpServletRequest httpServletRequest;

    protected HttpServletResponse httpServletResponse;

    public void setServletResponse(HttpServletResponse httpServletResponse) {
        this.httpServletResponse = httpServletResponse;
    }

    public void setSession(Map<String, Object> stringObjectMap) {
        this.session = stringObjectMap;
    }

    public void setRequest(Map<String, Object> stringObjectMap) {
        this.request = stringObjectMap;
    }

    public void setParameters(Map<String, String[]> stringMap) {
        this.parameters = stringMap;
    }

    public void setServletRequest(HttpServletRequest httpServletRequest) {
        this.httpServletRequest = httpServletRequest;
    }

    // 这三个 reader 方法是给页面标签使用的。

    public Map<String, Object> getSession() {
        return session;
    }

    public Map<String, Object> getRequest() {
        return request;
    }

    public Map<String, String[]> getParameters() {
        return parameters;
    }

    /**
     * 获取请求参数值
     *
     * @param name         参数名
     * @param defaultValue 缺省值
     *
     * @return 请求参数值。如果参数值为空，则返回 defaultValue。
     */
    protected String p(String name, String defaultValue) {
        String[] values = parameters.get(name);

        if (ArrayUtils.isEmpty(values)) {
            return defaultValue;
        }

        return values[0] == null ? defaultValue : values[0];
    }

    /**
     * 获取请求参数值
     *
     * @param name 参数名
     *
     * @return 请求参数值。如果参数值为空，则返回空字符串
     */
    protected String p(String name) {
        return p(name, "");
    }

    /**
     * 从所有可能的参数名中获取请求参数值
     *
     * @param names 可能的参数名称
     *
     * @return 参数值。如果所有参数都不存在，则返回 null。
     */
    protected String pNames(String... names) {
        for (String name : names) {
            if (paramExists(name)) {
                return p(name);
            }
        }
        return null;
    }

    protected String[] pValues(String name) {
        String[] values = parameters.get(name);
        if (values == null) {
            values = new String[]{};
        }
        return values;
    }

    /**
     * 设置上下文对象。对象可以在 JSP 页面中以 "#xxx" 的方式获取。例如：
     * <p><code>setContextValue("now", new Date())</code></p>
     * 那么 JSP 页面中获取的方式就是：
     * <code>
     * <p>&lt;s:property value="#now"/&gt;</p>
     * </code>
     *
     * @param name  名称
     * @param value 值
     */
    protected void setContextValue(String name, Object value) {
        ActionContext.getContext().put(name, value);
    }

    /**
     * 获取头信息中包含的字符串
     *
     * @param headerName   参数名
     * @param defaultValue 缺省值
     * @param len          要截取的字符串长度。如果 strLen &lt; 0，
     *                     则表示截取字符串的后半部分，如果为 null 则表示取整个值。
     *
     * @return header 值的截取结果。如果不存在，则返回缺省值。
     */
    protected String getHeader(String headerName, String defaultValue, Integer len) {
        String result = null;

        if (httpServletRequest != null) {
            result = httpServletRequest.getHeader(headerName);
        }

        if (result == null) {
            result = defaultValue;

        } else if (len != null) {
            if (len > 0) {
                // 从左边开始获取指定数目字符
                result = result.substring(0, len);
            } else {
                // 从右边开始获取指定数目字符
                result = result.substring(result.length() + len);
            }
        }
        return result;
    }


    /**
     * 或缺请求 header 值
     *
     * @param headerName   header 名称
     * @param defaultValue 缺省值
     *
     * @return header 值。如果不存在，则返回缺省值。
     */
    public String getHeader(String headerName, String defaultValue) {
        return getHeader(headerName, defaultValue, null);
    }

    protected Integer pInt(String name) {
        return pInt(name, 0);
    }

    protected Integer pInt(String name, Integer defaultValue) {
        try {
            return Integer.parseInt(p(name).trim());
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    protected boolean paramExists(String name) {
        return p(name, null) != null;
    }

    // 将所有参数构造成字符串

    public static String serializeParams(Map<String, String[]> parameters) {
        return serializeParams(parameters, "");
    }

    // 将所有参数构造成字符串，除了指定的参数名外

    public static String serializeParams(Map<String, String[]> parameters, String... exceptions) {
        String result = "";

        try {
            for (String key : parameters.keySet()) {
                if (ArrayUtils.contains(exceptions, key)) {
                    continue;
                }

                String[] values = parameters.get(key);
                for (String value : values) {
                    if (value != null) {
                        result += key + "=" + URLEncoder.encode(value, "UTF-8") + "&";
                    }
                }
            }
            result = StringUtils.removeEnd(result, "&");
        } catch (UnsupportedEncodingException e) {
            // nothing to do
        }
        return result;
    }

    protected long pLong(String name, long defaultValue) {
        try {
            return Long.parseLong(p(name));
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    protected String getRequestURI() {
        return httpServletRequest == null ? "" : httpServletRequest.getRequestURI();
    }

    protected String getWebrootURI() {
        return "http://" + httpServletRequest.getServerName() +
                (httpServletRequest.getServerPort() == 80 ? "" : (":" + httpServletRequest.getServerPort())) +
                httpServletRequest.getContextPath();
    }
}
